/*
 * 百度在线网络技术（北京）有限公司拥有本软件版权2022并保留所有权利。
 * Copyright 2022, Baidu.com,Inc 2:Baidu Online Network Technology (Beijing) Co.,Ltd,
 * All rights reserved.
 */

package com.azdebugit.sync.hronized.waitnotiy;

import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

public class MyProductAndConsume {

    volatile static int NUM = 1;

    AtomicInteger atomicInteger = new AtomicInteger(0);

    final Object productLock = Object.class;
    final Object consumeLock = int[].class;
    final ReentrantLock lock = new ReentrantLock();

    final class MyWorkProduct implements Callable {
        public Object call() throws Exception{
            while (true) {
                Thread.sleep(500);
                synchronized (atomicInteger) {
                    while (atomicInteger.get() >= 1)  //已有生产的产品（while是为了同时只能一个生产者工作）
                        atomicInteger.wait(); //阻塞当前线程
                    System.out.println(Thread.currentThread().getName() + "-MyWorkProduct : " + ++NUM);
                    atomicInteger.incrementAndGet();
                    atomicInteger.notifyAll();
                }
            }
        }
    }

    final class MyWorkConsume implements Callable {
        public Object call() throws Exception{
            while (true) {
                Thread.sleep(new Random().nextInt(8000) + 500);
                synchronized (atomicInteger) {
                    while (atomicInteger.get() <= 0)  //无可消费产品（while是为了同时只能一个消费者消费）
                        atomicInteger.wait();
                    System.out.println(Thread.currentThread().getName() + "-MyWorkConsume : " + NUM);
                    atomicInteger.getAndDecrement();
                    atomicInteger.notifyAll();
                }
            }
        }
    }

    public void execute() {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        executorService.submit(new MyWorkProduct());executorService.submit(new MyWorkProduct());
        executorService.submit(new MyWorkConsume());executorService.submit(new MyWorkConsume());executorService.submit(new MyWorkConsume());
    }

    public static void main(String[] args) {
        new MyProductAndConsume().execute();
    }
}